﻿using System;
using System.Runtime.InteropServices;

namespace Jodell.Transport.Ethercat
{
    // 定义委托
    public delegate int PO2SOconfigDelegate(ushort slave);
    public delegate int PO2SOconfigxDelegate(IntPtr context, ushort slave);

    /** record for FMMU */
    [StructLayout(LayoutKind.Sequential, Pack = 1)]
    public struct ec_fmmut
    {
        UInt32 LogStart;
        UInt16 LogLength;
        Byte LogStartbit;
        Byte LogEndbit;
        UInt16 PhysStart;
        Byte PhysStartBit;
        Byte FMMUtype;
        Byte FMMUactive;
        Byte unused1;
        UInt16 unused2;
    }
    /** record for sync manager */
    [StructLayout(LayoutKind.Sequential, Pack = 1)]
    public struct ec_smt
    {
        UInt16 StartAddr;
        UInt16 SMlength;
        UInt32 SMflags;
    }
    [StructLayout(LayoutKind.Sequential, Pack = 1)]
    public struct ec_state_status
    {
        UInt16 State;
        UInt16 Unused;
        UInt16 ALstatuscode;
    }


    /** for list of ethercat slaves detected */
    [StructLayout(LayoutKind.Sequential)]
    public struct ec_slave
    {
        /** state of slave */
        public UInt16 state;
        /** AL status code */
        public UInt16 ALstatuscode;
        /** Configured address */
        public UInt16 configadr;
        /** Alias address */
        public UInt16 aliasadr;
        /** Manufacturer from EEprom */
        public UInt32 eep_man;
        /** ID from EEprom */
        public UInt32 eep_id;
        /** revision from EEprom */
        public UInt32 eep_rev;
        /** Interface type */
        public UInt16 Itype;
        /** Device type */
        public UInt16 Dtype;
        /** output bits */
        public UInt16 Obits;
        /** output bytes, if Obits < 8 then Obytes = 0 */
        public UInt32 Obytes;
        /** output pointer in IOmap buffer */
        public IntPtr outputs;//byte* 
        /** startbit in first output byte */
        public byte Ostartbit;
        /** input bits */
        public UInt16 Ibits;
        /** input bytes, if Ibits < 8 then Ibytes = 0 */
        public UInt32 Ibytes;
        /** input pointer in IOmap buffer */
        public IntPtr inputs;//byte* 
        /** startbit in first input byte */
        public byte Istartbit;
        /** SM structure */
        [MarshalAs(UnmanagedType.ByValArray, SizeConst = Constants.EC_MAXSM)]
        public ec_smt[] SM;
        /** SM type 0=unused 1=MbxWr 2=MbxRd 3=Outputs 4=Inputs */
        [MarshalAs(UnmanagedType.ByValArray, SizeConst = Constants.EC_MAXSM)]
        public byte[] SMtype;
        /** FMMU structure */
        [MarshalAs(UnmanagedType.ByValArray, SizeConst = Constants.EC_MAXFMMU)]
        public ec_fmmut[] FMMU;
        /** FMMU0 function */
        public byte FMMU0func;
        /** FMMU1 function */
        public byte FMMU1func;
        /** FMMU2 function */
        public byte FMMU2func;
        /** FMMU3 function */
        public byte FMMU3func;
        /** length of write mailbox in bytes, if no mailbox then 0 */
        public UInt16 mbx_l;
        /** mailbox write offset */
        public UInt16 mbx_wo;
        /** length of read mailbox in bytes */
        public UInt16 mbx_rl;
        /** mailbox read offset */
        public UInt16 mbx_ro;
        /** mailbox supported protocols */
        public UInt16 mbx_proto;
        /** Counter value of mailbox link layer protocol 1..7 */
        public byte mbx_cnt;
        /** has DC capability */
        [MarshalAs(UnmanagedType.U1)]
        public bool hasdc;
        /** Physical type; Ebus, EtherNet combinations */
        public byte ptype;
        /** topology: 1 to 3 links */
        public byte topology;
        /** active ports bitmap : ....3210 , set if respective port is active **/
        public byte activeports;
        /** consumed ports bitmap : ....3210, used for internal delay measurement **/
        byte consumedports;
        /** slave number for parent, 0=master */
        public UInt16 parent;
        /** port number on parent this slave is connected to **/
        public byte parentport;
        /** port number on this slave the parent is connected to **/
        public byte entryport;
        /** DC receivetimes on port A */
        public Int32 DCrtA;
        /** DC receivetimes on port B */
        public Int32 DCrtB;
        /** DC receivetimes on port C */
        public Int32 DCrtC;
        /** DC receivetimes on port D */
        public Int32 DCrtD;
        /** propagation delay */
        public Int32 pdelay;
        /** next DC slave */
        public UInt16 DCnext;
        /** previous DC slave */
        public UInt16 DCprevious;
        /** DC cycle time in ns */
        public Int32 DCcycle;
        /** DC shift from clock modulus boundary */
        public Int32 DCshift;
        /** DC sync activation, 0=off, 1=on */
        public byte DCactive;
        /** link to config table */
        public UInt16 configindex;
        /** link to SII config */
        public UInt16 SIIindex;
        /** 1 = 8 bytes per read, 0 = 4 bytes per read */
        public byte eep_8byte;
        /** 0 = eeprom to master , 1 = eeprom to PDI */
        public byte eep_pdi;
        /** CoE details */
        public byte CoEdetails;
        /** FoE details */
        public byte FoEdetails;
        /** EoE details */
        public byte EoEdetails;
        /** SoE details */
        public byte SoEdetails;
        /** E-bus current */
        Int16 Ebuscurrent;
        /** if >0 block use of LRW in processdata */
        public byte blockLRW;
        /** group */
        public byte group;
        /** first unused FMMU */
        public byte FMMUunused;
        /** Boolean for tracking whether the slave is (not) responding, not used/set by the SOEM library */
        [MarshalAs(UnmanagedType.U1)]
        public bool islost;
        /** registered configuration function PO->SO, (DEPRECATED)*/
        [MarshalAs(UnmanagedType.FunctionPtr)]
        public PO2SOconfigDelegate PO2SOconfig;// int (* PO2SOconfig) (UInt16 slave);
        /** registered configuration function PO->SO */
        [MarshalAs(UnmanagedType.FunctionPtr)]
        public PO2SOconfigxDelegate PO2SOconfigx;//int (* PO2SOconfigx) (ecx_contextt* context, UInt16 slave);
        /** readable name */
        //char name[EC_MAXNAME + 1];
        [MarshalAs(UnmanagedType.ByValTStr, SizeConst = Constants.EC_MAXNAME + 1)]
        public string name;
    }

    /** for list of ethercat slave groups */
    [StructLayout(LayoutKind.Sequential)]
    public struct ec_group
    {
        /** logical start address for this group */
        UInt32 logstartaddr;
        /** output bytes, if Obits < 8 then Obytes = 0 */
        UInt32 Obytes;
        /** output pointer in IOmap buffer */
        IntPtr outputs;//byte*
        /** input bytes, if Ibits < 8 then Ibytes = 0 */
        UInt32 Ibytes;
        /** input pointer in IOmap buffer */
        IntPtr inputs;//byte*
        /** has DC capabillity */
        [MarshalAs(UnmanagedType.U1)]
        bool hasdc;
        /** next DC slave */
        UInt16 DCnext;
        /** E-bus current */
        Int16 Ebuscurrent;
        /** if >0 block use of LRW in processdata */
        byte blockLRW;
        /** IO segments used */
        UInt16 nsegments;
        /** 1st input segment */
        UInt16 Isegment;
        /** Offset in input segment */
        UInt16 Ioffset;
        /** Expected workcounter outputs */
        UInt16 outputsWKC;
        /** Expected workcounter inputs */
        UInt16 inputsWKC;
        /** check slave states */
        [MarshalAs(UnmanagedType.U1)]
        bool docheckstate;
        /** IO segmentation list. Datagrams must not break SM in two. */
        [MarshalAs(UnmanagedType.ByValArray, SizeConst = Constants.EC_MAXIOSEGMENTS)]
        UInt32[] IOsegment;
    }

    /** SII FMMU structure */
    [StructLayout(LayoutKind.Sequential)]
    public struct ec_eepromFMMU
    {
        UInt16 Startpos;
        byte nFMMU;
        byte FMMU0;
        byte FMMU1;
        byte FMMU2;
        byte FMMU3;
    }

    /** SII SM structure */
    [StructLayout(LayoutKind.Sequential)]
    public struct ec_eepromSM
    {
        UInt16 Startpos;
        byte nSM;
        UInt16 PhStart;
        UInt16 Plength;
        byte Creg;
        byte Sreg;       /* don't care */
        byte Activate;
        byte PDIctrl;      /* don't care */
    }

    /** for list of ethercat slaves detected */
    [StructLayout(LayoutKind.Sequential)]
    public struct EcSlaveInfo
    {
        [MarshalAs(UnmanagedType.ByValTStr, SizeConst = Constants.EC_MAXNAME + 1)]
        public string Name;
        public IntPtr Inputs;
        public IntPtr Outputs;
        public UInt32  Manufacturer;
        public UInt32 ProductCode;
        public UInt32 Revision;
        public UInt16 OldCsa;
        public UInt16 Csa;
    }
}
